#!/usr/bin/python
# -*- coding: utf8 -*-
#Programa: llistaCompra.py
#Fecha: 8/10/2010
#Fecha modificación: 21/10/2010
#Autor: Iván Viguera
#Descripción:
#   Programa que ajuda a mantenir la llista de la compra
#   Probado con una clase.
#   Uso de diccionario como switch.

#----Funciones----

#---Clases---
class llistaCompra:
    #---Métodos---
    def __init__(self):
        self.listaCompra = dict({'per defecte':[]})
        self.salir = False
        self.listaActual = 'per defecte'
    
    ##a. Demana un string i, si no hi és a la llista,
    ##el col·loca al final de la llista. Altrament mostra un missatge d'error
    def demanaElement(self):
        element = raw_input("Producte: ")
        if not element in self.listaCompra[self.listaActual]:
            self.listaCompra[self.listaActual].append(element)
        else:
            print element,"ja es a la llista."
    
    ##b. Demana confirmació. Si confirma, elimina tots els elements de la llista
    def removeAll(self):
        if self.__missatgeConfirmacio__():
            del self.listaCompra[self.listaActual][0:len(self.listaCompra)]
        
    ##e. Demana un string i, si hi és a la llista l'elimina tot demanant confirmació.
    ##    Si no hi era a la llista, mostra un missatge d'error.
    def eliminaElement(self):
        element = raw_input("Introdueixi l'element a eliminar: ")
        if element in self.listaCompra[self.listaActual]:
            if self.__missatgeConfirmacio__():
                self.listaCompra[self.listaActual].remove(element)
        else:
            print element,"no existeix."

    ##h. Demana un string i comprova si hi és o no a la llista. Mostra un missatge adequat.
    def existe(self):
        resp = raw_input("Paraula a buscar: ")
        if resp in self.listaCompra[self.listaActual] :
            print "Esta"
        else :
            print "No esta"
            
    ##m. Mostra el contingut de la llista ordenat alfabèticament.
    ##Atenció, no canvia l'ordre intern de la llista! En cas que la
    ##llista estigui buida, ho indica amb un missatge.
    def listaOrdenada(self):
        if len(self.listaCompra[self.listaActual])>0:
            listaAux = self.listaCompra[self.listaActual][:]
            listaAux.sort()
            for i in listaAux:
                print i
        else:
            print "Llista buida."

    ##q. Mostra quants elements hi ha a la llista
    def quantitatElements(self):
        print len(self.listaCompra[self.listaActual])

    ##x. Demana confirmació de sortida i, si confirma, finalitza l'execució del programa.
    def sortir(self):
        self.salir = self.__missatgeConfirmacio__()

##    Gestió de llistes:

##  lc: canvia la llista actual
##demana el nom d'una llista, i si existeix canvia la llista actual per la nova.
    def changeList(self):
        listAux = raw_input('Llista a la que es vol treballar: ')
        if listAux in self.listaCompra.keys():
            self.listaActual = listAux
        else:
            print 'Cap llista creada amb aquest nom'
            
##  le: elimina una llista
##   demana el nom d'una llista i si existeix i no és l'actual, demana confirmació a l'usuari. En cas que
##confirmi, elimina la llista indicada. En cas que es demani l'actual, mostra el missatge d'error:
    def eliminaLlista(self):
        listAux = raw_input('Llista que es vol eliminar: ')
        if not listAux in self.listaCompra.keys():
            print 'No existeix la llista.'
            return -1
        if listAux == self.listaActual:
            print 'No es pot eliminar la llista actual'
            return -2
        if self.__missatgeConfirmacio__():
            self.listaCompra.pop(listAux)    

##  ll: llista el nom de totes les llistes
##mostra el nom de totes les llistes acompanyat, entre parèntesis, del nombre d'elements que conté cada
##llista. Per exemple, si tenim les llistes “material informàtic” amb tres elements, “per defecte” amb cap
##element i “compres personals” amb un element, la sortida serà:
    def nomLlistes(self):
        for key in self.listaCompra.keys():
            cuantitat = len(self.listaCompra[key])
            text = 'cap element'
            if cuantitat == 1:
                text = str(cuantitat)+' element'
            elif cuantitat > 1:
                text = str(cuantitat)+' elements'
            print key,'(',text,')'    
            
##  lm: mou el contingut d'una llista a l'actual demana el nom d'una llista i si existeix i no és l'actual, demana confirmació a l'usuari. En cas que
##confirmi, afegeix el contingut de la nova llista al final de la llista actual i deixa l'altra llista buida. En cas
##que es demani moure de la llista actual, s'indicarà amb l'error:
    def llistaNtoLlistaActual(self):
        listAux = raw_input("Llista que es vol unir a l'actual: ")
        if not listAux in self.listaCompra.keys():
            print 'No existeix la llista.'
            return -1
        if listAux == self.listaActual:
            print 'No es pot moure de la llista actual a si mateixa'
            return -2
        if self.__missatgeConfirmacio__():
            self.listaCompra[self.listaActual]+=self.listaCompra[listAux]
            del self.listaCompra[listAux][:]

##  ln: crea una nova llista
    def novaLlista(self):
        listAux = raw_input("Nom de la nova llista: ")
        if listAux in self.listaCompra.keys():
            print 'Ja existeix una llista amb aquest nom'
            return -1
        self.listaCompra[listAux]=[]

##  lr: reanomena la llista actual
    def renombrarListaActual(self):
        listAux = raw_input("Nom a renombrar llista: ")
        if listAux in self.listaCompra.keys():
            print 'Ja existeix una llista amb aquest nom'
            return -1
        self.listaCompra[listAux] = self.listaCompra[self.listaActual][:]
        self.listaCompra.pop(self.listaActual)    
        self.listaActual = listAux 
        
##  lt: cerca un element a les llistes
    def cercarElement(self):
        element = raw_input("Element a buscar: ")
        listAux=[]
        for key in self.listaCompra.keys():
            if element in self.listaCompra[key]:
                listAux.append(key)
        text = 'Element no trobat a cap llista'
        if len(listAux)>0:
            text = listAux
        print text

    #Retorna True/False segons el que hagi introduït l'usuari.    
    def __missatgeConfirmacio__(self):
        resp = raw_input("Confirmar acció[s]: ")
        return resp is "s"
    
    def getNomLlistaActual(self):
        return self.listaActual
#----Main----
def main():
    opcionsMenu = ('lc: canvia la llista actual',
                   'le: elimina una llista',
                   'll: llista el nom de totes les llistes',
                   "lm: mou el contingut d'una llista a l'actual",
                   "ln: crea una nova llista",
                   'lr: reanomena la llista actual',
                   'lt: cerca un element a les llistes',
                    '\n',
                   "a. afegeix a la llista",
                   "b. buida la llista",
                   "e. elimina de la llista",
                   "h. hi Ès a la llista?",
                   "m. mostra la llista",
                   "q. quants?",
                   "x. surt del programa"
                )

    lC = llistaCompra()

    #Define un switch con las opciones a partir del uso de diccionarios.
    opciones = dict({'a':lC.demanaElement,
                'b':lC.removeAll,
                'e':lC.eliminaElement,
                'h':lC.existe,
                'm':lC.listaOrdenada,
                'q':lC.quantitatElements,
                'x':lC.sortir,
                'lc': lC.changeList,
               'le': lC.eliminaLlista,
               'll':lC.nomLlistes,
               'lm': lC.llistaNtoLlistaActual,
               'ln': lC.novaLlista,
               'lr': lC.renombrarListaActual,
               'lt': lC.cercarElement
            })

    while not lC.salir :
        print 'Llista actual:', lC.getNomLlistaActual()
        #pintar el menú
        for op in opcionsMenu:
            print op
        try:
            opciones.get(raw_input("Opció: "))()
        except Exception,e:
            print e
            pass
        print "\n"
   
main()
